package org.jeecg.modules.wmhb.controller;

import java.text.SimpleDateFormat;
import java.util.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.UserConstant;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.common.system.vo.SelectTreeModel;
import org.jeecg.modules.wmhb.dto.req.ProductBomReqDto;
import org.jeecg.modules.wmhb.entity.*;
import org.jeecg.modules.wmhb.service.*;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;

import org.jeecg.modules.wmhb.vo.SelectContractTreeModel;
import org.jeecg.modules.wmhb.dto.res.ProductBomResDto;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecg.common.system.base.controller.JeecgController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.apache.shiro.authz.annotation.RequiresPermissions;

/**
 * @Description: 合同产品清单
 * @Author: jeecg-boot
 * @Date: 2024-09-07
 * @Version: V1.0
 */
@Tag(name = "合同产品清单")
@RestController
@RequestMapping("/wmhb/wmContractProduct")
@Slf4j
public class WmContractProductController extends JeecgController<WmContractProduct, IWmContractProductService> {
    @Autowired
    private IWmContractProductService wmContractProductService;
    @Autowired
    private IWmContractService wmContractService;
    @Autowired
    private IWmPlanService wmPlanService;

    /**
     * 分页列表查询
     *
     * @param wmContractProduct
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    //@AutoLog(value = "合同产品清单-分页列表查询")
    @Operation(summary = "合同产品清单-分页列表查询")
    @GetMapping(value = "/rootList")
    public Result<IPage<WmContractProduct>> queryPageList(WmContractProduct wmContractProduct,
                                                          @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                          @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                                          HttpServletRequest req) {
        String hasQuery = req.getParameter("hasQuery");
        if (hasQuery != null && "true".equals(hasQuery)) {
            QueryWrapper<WmContractProduct> queryWrapper = QueryGenerator.initQueryWrapper(wmContractProduct, req.getParameterMap());
            List<WmContractProduct> list = wmContractProductService.queryTreeListNoPage(queryWrapper);
            IPage<WmContractProduct> pageList = new Page<>(1, 10, list.size());
            pageList.setRecords(list);
            return Result.OK(pageList);
        } else {
            String parentId = wmContractProduct.getPid();
            if (oConvertUtils.isEmpty(parentId)) {
                parentId = "0";
            }
            wmContractProduct.setPid(null);
            QueryWrapper<WmContractProduct> queryWrapper = QueryGenerator.initQueryWrapper(wmContractProduct, req.getParameterMap());
            // 使用 eq 防止模糊查询
            queryWrapper.eq("pid", parentId);
            Page<WmContractProduct> page = new Page<WmContractProduct>(pageNo, pageSize);
            IPage<WmContractProduct> pageList = wmContractProductService.page(page, queryWrapper);
            return Result.OK(pageList);
        }
    }

    /**
     * 【vue3专用】加载节点的子数据
     *
     * @param pid
     * @return
     */
    @RequestMapping(value = "/loadTreeChildren", method = RequestMethod.GET)
    public Result<List<SelectTreeModel>> loadTreeChildren(@RequestParam(name = "pid") String pid) {
        Result<List<SelectTreeModel>> result = new Result<>();
        try {
            List<SelectTreeModel> ls = wmContractProductService.queryListByPid(pid);
            result.setResult(ls);
            result.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            result.setMessage(e.getMessage());
            result.setSuccess(false);
        }
        return result;
    }

    /**
     * 【vue3专用】加载一级节点/如果是同步 则所有数据
     *
     * @param async
     * @param pcode
     * @param wmContractId
     * @return
     */
    @Operation(summary = "合同产品清单-加载一级节点/如果是同步 则所有数据")
    @RequestMapping(value = "/loadTreeRoot", method = RequestMethod.GET)
    public Result<List<SelectContractTreeModel>> loadTreeRoot(@RequestParam(name = "async") Boolean async, @RequestParam(name = "pcode", required = false) String pcode, @RequestParam(name = "wmContractId") String wmContractId) {
        Result<List<SelectContractTreeModel>> result = new Result<>();
        try {
            List<SelectContractTreeModel> ls = wmContractProductService.queryListByCodeAndContract(pcode, wmContractId);
            if (!async) {
                loadAllChildren(ls);
            }
            result.setResult(ls);
            result.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            result.setMessage(e.getMessage());
            result.setSuccess(false);
        }
        return result;
    }

    /**
     * 【vue3专用】递归求子节点 同步加载用到
     *
     * @param ls
     */
    private void loadAllChildren(List<SelectContractTreeModel> ls) {
        for (SelectContractTreeModel tsm : ls) {
            List<SelectContractTreeModel> temp = wmContractProductService.queryListByPidAndContract(tsm.getKey());
            if (temp != null && temp.size() > 0) {
                tsm.setChildren(temp);
                loadAllChildren(temp);
            }
        }
    }

    /**
     * 获取子数据
     *
     * @param wmContractProduct
     * @param req
     * @return
     */
    //@AutoLog(value = "合同产品清单-获取子数据")
    @Operation(summary = "合同产品清单-获取子数据")
    @GetMapping(value = "/childList")
    public Result<IPage<WmContractProduct>> queryPageList(WmContractProduct wmContractProduct, HttpServletRequest req) {
        QueryWrapper<WmContractProduct> queryWrapper = QueryGenerator.initQueryWrapper(wmContractProduct, req.getParameterMap());
        List<WmContractProduct> list = wmContractProductService.list(queryWrapper);
        IPage<WmContractProduct> pageList = new Page<>(1, 10, list.size());
        pageList.setRecords(list);
        return Result.OK(pageList);
    }

    /**
     * 批量查询子节点
     *
     * @param parentIds 父ID（多个采用半角逗号分割）
     * @param parentIds
     * @return 返回 IPage
     * @return
     */
    //@AutoLog(value = "合同产品清单-批量获取子数据")
    @Operation(summary = "合同产品清单-批量获取子数据")
    @GetMapping("/getChildListBatch")
    public Result getChildListBatch(@RequestParam("parentIds") String parentIds) {
        try {
            QueryWrapper<WmContractProduct> queryWrapper = new QueryWrapper<>();
            List<String> parentIdList = Arrays.asList(parentIds.split(","));
            queryWrapper.in("pid", parentIdList);
            List<WmContractProduct> list = wmContractProductService.list(queryWrapper);
            IPage<WmContractProduct> pageList = new Page<>(1, 10, list.size());
            pageList.setRecords(list);
            return Result.OK(pageList);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.error("批量查询子节点失败：" + e.getMessage());
        }
    }

    /**
     * 添加
     *
     * @param wmContractProduct
     * @return
     */
    @AutoLog(value = "合同产品清单-添加")
    @Operation(summary = "合同产品清单-添加")
    @RequiresPermissions("wmhb:wm_contract_product:add")
    @PostMapping(value = "/add")
    public Result<String> add(@RequestBody WmContractProduct wmContractProduct) {
        if (wmContractProduct.getLevel() == null) {
            wmContractProduct.setLevel(0);
        }
        wmContractProductService.addWmContractProduct(wmContractProduct);
        return Result.OK("添加成功！");
    }

    /**
     * 编辑
     *
     * @param wmContractProduct
     * @return
     */
    @AutoLog(value = "合同产品清单-编辑")
    @Operation(summary = "合同产品清单-编辑")
    @RequiresPermissions("wmhb:wm_contract_product:edit")
    @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<String> edit(@RequestBody WmContractProduct wmContractProduct) {
//        List<WmTaskbook> wmTaskbookList = wmTaskbookService.selectByContractProduct(wmContractProduct.getId());
//        if(!wmTaskbookList.isEmpty()){
//            //return Result.error("该产品下已有任务书，不能修改");
//        }

        wmContractProductService.updateWmContractProduct(wmContractProduct);
        return Result.OK("编辑成功!");
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "合同产品清单-通过id删除")
    @Operation(summary = "合同产品清单-通过id删除")
    @RequiresPermissions("wmhb:wm_contract_product:delete")
    @DeleteMapping(value = "/delete")
    @Transactional
    public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
        WmContractProduct wmContractProduct = wmContractProductService.getById(id);
        if (wmContractProductService.checkHasItem(id)) {
            return Result.error("产品下是否有子产品，请先删除子产品");
        }

//        List<WmTaskbook> wmTaskbookList = wmTaskbookService.selectByContractProduct(wmContractProduct.getId());
//        if(!wmTaskbookList.isEmpty()){
//            return Result.error("该产品下已有任务书，不能删除");
//        }

        //删除产品
        wmContractProductService.deleteWmContractProduct(id);
        return Result.OK("删除成功!");
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    //@AutoLog(value = "合同产品清单-通过id查询")
    @Operation(summary = "合同产品清单-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<WmContractProduct> queryById(@RequestParam(name = "id", required = true) String id) {
        WmContractProduct wmContractProduct = wmContractProductService.getById(id);
        if (wmContractProduct == null) {
            return Result.error("未找到对应数据");
        }
        return Result.OK(wmContractProduct);
    }

    /**
     * 通过excel导入数据
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/importExcel/{wmContractId}", method = RequestMethod.POST)
    @RequiresPermissions("wmhb:wm_contract_product:importExcel")
    @Operation(summary = "合同产品清单-通过excel导入数据")
    @Transactional
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response, @PathVariable("wmContractId") String wmContractId) {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
            // 获取上传文件对象
            MultipartFile file = entity.getValue();
            ImportParams params = new ImportParams();
            params.setTitleRows(0);
            params.setHeadRows(1);
            params.setNeedSave(true);
            try {
                List<ProductBomReqDto> list = ExcelImportUtil.importExcel(file.getInputStream(), ProductBomReqDto.class, params);
                ProductBomResDto wmBomResultVo = uploadProductProcess(list, wmContractId);
                return Result.ok(wmBomResultVo);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                throw new RuntimeException(e.getMessage());
            } finally {
                try {
                    file.getInputStream().close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return Result.error("文件导入失败！");
    }

    private ProductBomResDto uploadProductProcess(List<ProductBomReqDto> list, String wmContractId) {
        List<ProductBomReqDto> newList = new ArrayList<>();
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
        String batchNo = format.format(new Date());
        try {
            //A、修改合同状态为已导入

            WmContract wmContract = wmContractService.getById(wmContractId);
            List<String> statusList = new ArrayList<>();
            statusList.add(UserConstant.CONTRACT_STATUS_CONFIRMED);
            statusList.add(UserConstant.CONTRACT_STATUS_IMPORTED);
            if (wmContract != null && !statusList.contains(wmContract.getStatus())) {
                throw new RuntimeException("当前合同状态不允许导入");
            }
            wmContract.setStatus(UserConstant.CONTRACT_STATUS_IMPORTED);
            wmContract.setBatchNo(batchNo);
            wmContractService.updateById(wmContract);

            //B、循环处理上传的产品
            for (ProductBomReqDto bomNode : list) {
                if (StringUtils.isEmpty(bomNode.getName())) {
                    bomNode.setStatus("物料名称缺失");
                    bomNode.setResult("fail");
                    newList.add(bomNode);
                    continue;
                }

                if (bomNode.getBomType() != null && StringUtils.isEmpty(bomNode.getCode())) {
                    bomNode.setStatus("物料编码缺失");
                    bomNode.setResult("fail");
                    newList.add(bomNode);
                    continue;
                }

                //新增合同产品信息
                wmContractProductService.saveContractProductWhenImport(bomNode, wmContractId, batchNo);
                bomNode.setStatus("导入成功");
                bomNode.setResult("success");
                newList.add(bomNode);
            }
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }

        ProductBomResDto wmBomResultVo = new ProductBomResDto();
        wmBomResultVo.setBomNodeList(newList);
        wmBomResultVo.setBatchNo(batchNo);
        return wmBomResultVo;
    }

    /**
     * 导入设备产品数据确认
     *
     * @param batchNo
     * @return
     */
    @AutoLog(value = "合同产品清单-导入设备产品数据确认")
    @Operation(summary = "合同产品清单-导入设备产品数据确认")
    @RequiresPermissions("wmhb:wm_contract_product:confirm")
    @RequestMapping(value = "/confirm", method = {RequestMethod.PUT, RequestMethod.POST})
    @Transactional
    public Result<String> doConfirm(@RequestParam(name = "batchNo", required = true) String batchNo) {
        if (StringUtils.isEmpty(batchNo)) {
            return Result.error("请先导入合同产品");
        }
        //1、修改合同状态为已导入
        LambdaUpdateWrapper<WmContract> updateWrapper1 = new LambdaUpdateWrapper<>();
        updateWrapper1.set(WmContract::getStatus, UserConstant.CONTRACT_STATUS_IMPORT_CONFIRMED)
                //.set(WmContract::getProgress, "20")
                .eq(WmContract::getBatchNo, batchNo);
        wmContractService.update(null, updateWrapper1);

        //2、合同产品确认
        LambdaUpdateWrapper<WmContractProduct> updateWrapper4 = new LambdaUpdateWrapper<>();
        updateWrapper4.set(WmContractProduct::getEnableFlag, UserConstant.ENABLE_FLAG_YES).eq(WmContractProduct::getBatchNo, batchNo);
        wmContractProductService.update(null, updateWrapper4);
        return Result.OK("操作成功");
    }

    /**
     * 通过批次号批量删除
     *
     * @param batchNo
     * @return
     */
    @AutoLog(value = "合同产品清单-通过批次号批量删除")
    @Operation(summary = "合同产品清单-通过批次号批量删除")
    @RequiresPermissions("wmhb:wm_contract_product:deleteBatch")
    @DeleteMapping(value = "/deleteByBatchNo")
    @Transactional
    public Result<String> deleteByBatchNo(@RequestParam(name = "batchNo", required = true) String batchNo) {
        if (StringUtils.isEmpty(batchNo)) {
            return Result.OK("批量删除成功!");
        }

        WmContract wmContract = wmContractService.queryByBachNo(batchNo);
        List<String> statusList = new ArrayList<>();
        statusList.add(UserConstant.CONTRACT_STATUS_CONFIRMED);
        statusList.add(UserConstant.CONTRACT_STATUS_IMPORTED);
        if (wmContract != null && !statusList.contains(wmContract.getStatus())) {
            throw new RuntimeException("当前合同状态不允许导入");
        }

        //1、修改合同状态回滚到已确认
        LambdaUpdateWrapper<WmContract> updateWrapper1 = new LambdaUpdateWrapper<>();
        updateWrapper1.set(WmContract::getStatus, UserConstant.CONTRACT_STATUS_CONFIRMED)
                .set(WmContract::getBatchNo, null)
                //.set(WmContract::getProgress, "10")
                .eq(WmContract::getBatchNo, batchNo);
        wmContractService.update(null, updateWrapper1);

        //2、删除合同产品
        LambdaQueryWrapper<WmContractProduct> queryWrapper4 = new LambdaQueryWrapper<>();
        queryWrapper4.eq(WmContractProduct::getBatchNo, batchNo);
        this.wmContractProductService.remove(queryWrapper4);
        return Result.OK("批量删除成功!");
    }

    /**
     * 通过产品清单最销售单位批量一键转换
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "合同产品清单-一键生成项目计划")
    @Operation(summary = "合同产品清单-一键生成项目计划")
    //@RequiresPermissions("wmhb:wm_contract_product:generatePlan")
    @PostMapping(value = "/generatePlan")
    public Result<String> generatePlan(@RequestParam(name = "ids", required = true) String ids) {
        List<String> idList = Arrays.asList(ids.split(","));
        wmPlanService.addWmPlanBatch(idList);
        return Result.OK("操作成功！");
    }
}
